home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- **
- ** >>>> CW.c of Saturday, 04 Mar 1995 12:40:24
- **************************************************************************
- ** Zweck:
- ** Zählt die Anzahl der Worte, die auf <Word> passen.
- ** oder die Anzahl Zeilen, die auf <Pattern> passen.
- **
- **************************************************************************
- **
- ** History
- **
- ** Version Datum Aenderungen
- ** ------- ----------- ------------------------------------------------
- 1.0 24 Feb 1995 Siehe History File
- 1.1 24 Feb 1995 Siehe History File
- 1.2 24 Feb 1995 Siehe History File
- 1.3 24 Feb 1995 Siehe History File
- 1.4 02 Mar 1995 Siehe History File
- 1.5 02 Mar 1995 Siehe History File
- 1.6 02 Mar 1995 Siehe History File
- 1.7 02 Mar 1995 Siehe History File
- 1.8 02 Mar 1995 Siehe History File
- 1.9 02 Mar 1995 Siehe History File
- 1.10 02 Mar 1995 Siehe History File
- 1.11 02 Mar 1995 Siehe History File
- 1.12 04 Mar 1995 Siehe History File
-
- **
- *** ts=2 ****************************************************************/
-
-
- #define __USE_SYSBASE aye
-
- #include <exec/exec.h>
- #include <proto/exec.h>
-
- #include <dos/dos.h>
- #include <proto/dos.h>
-
- #include <string.h>
-
- #include <own/CTRL-C.h>
-
- const char version[] = "\0$VER: CW 1.12 ("__DATE__"/"__TIME__")\0";
- const char *ver = &version[7];
-
- struct args {
- char *arg_File;
- char *arg_Word;
- ULONG arg_IgnCase;
- ULONG arg_Quiet;
- ULONG arg_InBuf;
- ULONG arg_InBufDef; // Hier steht der Defaultwert für InBuf, hat nix mit ReadArgs zu tun.
- } Args = { NULL, NULL, FALSE, FALSE, 1000, 1000 };
-
- const char template[] = "FILE/A,WORD/A,NC=NoCase/S,Q=Quiet/S,B=InBuf/N/K\n\0";
-
- BOOL MNC(STRPTR, STRPTR);
- BOOL MC(STRPTR, STRPTR);
-
- int PMatch(BPTR file, void *pat, BOOL (*func)(STRPTR, STRPTR));
- int WMatch(BPTR file);
-
- int main(void)
- {
- struct RDArgs *myrda;
- BPTR lock, fle;
- char *pattern;
- int fm, i;
-
- if(myrda = ReadArgs(template, (LONG *)&Args, NULL))
- {
-
- if(Args.arg_InBufDef != Args.arg_InBuf) Args.arg_InBuf = *(ULONG *)Args.arg_InBuf;
-
- if(lock = Lock(Args.arg_File, ACCESS_READ))
- {
- fle = OpenFromLock(lock);
- if(!fle)
- {
- PrintFault(IoErr(), "DOS");
- UnLock(lock);
- Printf("Konnte Suchfile %s nicht öffnen!\n", Args.arg_File);
- return RETURN_FAIL;
- }
- }
- else
- {
- PrintFault(IoErr(), "DOS");
- UnLock(lock);
- Printf("Konnte Suchfile %s nicht ansprechen!\n", Args.arg_File);
- return RETURN_FAIL;
- }
-
- if(pattern = AllocVec(3*strlen(Args.arg_Word), MEMF_ANY))
- {
- if(Args.arg_IgnCase)
- {
- if(ParsePatternNoCase(Args.arg_Word, pattern, 3*strlen(Args.arg_Word)))
- fm = PMatch(fle, pattern, MNC);
- else
- {
- for(i=0;i<strlen(Args.arg_Word); Args.arg_Word[i]=tolower(Args.arg_Word[i++]));
- fm = WMatch(fle);
- }
- }
- else
- {
- if(ParsePattern(Args.arg_Word, pattern, 3*strlen(Args.arg_Word)))
- fm = PMatch(fle, pattern, MC);
- else
- fm = WMatch(fle);
- }
- Printf( ((Args.arg_Quiet) ? "%ld\n" : "\nMatches found: [%ld]\n\n"), fm);
- FreeVec(pattern);
- }
-
- Close(fle);
- }
- return RETURN_OK;
- }
-
- BOOL MNC(STRPTR pat, STRPTR match)
- {
- return MatchPatternNoCase(pat, match);
- }
-
- BOOL MC(STRPTR pat, STRPTR match)
- {
- return MatchPattern(pat, match);
- }
-
- int PMatch(BPTR file, void *pat, BOOL (*func)(STRPTR, STRPTR))
- {
- BOOL goon = TRUE;
- char *buf;
- int i = 0, k = 0;
- ULONG sigs;
-
- if(buf = AllocVec(Args.arg_InBuf, MEMF_ANY|MEMF_CLEAR))
- {
- while(goon && !(sigs = CTRLC))
- {
- if(!Args.arg_Quiet) Printf("Scanning Line %ld, so far %ld.\r", ++k, i); // Ausgabe
- goon = FGets(file, buf, Args.arg_InBuf); // Bei Fehler oder EOF Schleife abbrechen
- if((goon) && (func(pat, buf))) i++; // Vergleichen, wenn nicht EOF erreicht
- }
-
- FreeVec(buf); // Inbuffer wieder freigeben
-
- if(sigs)
- {
- Printf("\n*** BREAK!\n");
- return i;
- }
-
- if(IoErr())
- {
- PrintFault(IoErr(), "DOS");
- Printf("Beim Scannen der Datei ist ein Fehler aufgetreten!\n");
- return 0;
- }
- }
- else
- {
- Printf( "Zu wenig Speicher für den Lesepuffer (%ld Bytes)!\n"
- "Bitte modifizieren Sie die Größe mittels des <InBuf>-Parameters!\n", Args.arg_InBuf);
- return 0;
- }
-
- return i;
- }
-
- int WMatch(BPTR file)
- {
- BOOL goon = TRUE;
- char *chlut;
- char *buf, c;
- int len, k, j, i, skip, buflen, cnt = 0;
- ULONG sigs;
-
- if(buf = AllocVec(Args.arg_InBuf, MEMF_ANY|MEMF_CLEAR))
- {
- len = strlen(Args.arg_Word);
-
- if(chlut = AllocVec(255, MEMF_ANY)) // Character LookUp Table erzeugen
- {
- for(i=0; i<255; chlut[i++]=len); // Alle Zeichen !e Word = len
- for(i=1; i<=len; chlut[Args.arg_Word[i-1]]=len-i++); // Zeichen e Word mit dem Abstand zum, Wortende
- }
- else
- {
- FreeVec(buf);
- Printf("Nicht genug freier Speicher für die Character LUT!\n");
- return 0;
- }
-
- k=0;
- while(goon)
- {
- goon = FGets(file, buf, Args.arg_InBuf); // Bei Fehler oder EOF Schleife abbrechen
-
- if(!Args.arg_Quiet) Printf("Scanning Line %ld, so far %ld.\r", ++k, cnt); // Ausgabe
-
- if(goon)
- {
- buflen = strlen(buf);
-
- if(Args.arg_IgnCase) for(i=0;i<buflen; buf[i]=tolower(buf[i++])); // Zeile in LoCase, wenn IgnCase
-
- j=len-1;
- while(j < buflen) // Bin ich noch im Buffer?
- {
- i=len;
- while((i) && (j < buflen) && !(sigs = CTRLC)) // Bin ich noch im Buffer?, CTRL-C gedrückt?
- {
- c = buf[j];
- if(Args.arg_Word[i-1] == c)
- {
- i--; // Ein Zeichen vornedran checken
- j--;
- }
- else
- {
- skip = chlut[c];
-
- /*
- ** Diese Abfrage hat mich schwer aufgehalten. Alle Zeichen, die Teil des Wortes sind, und rechts von dem
- ** fehlgeschlagenen Vergleich stehen, sind Teil des Wortes und damit bereits vorgekommen. Es kann daher nur
- ** sein, daß das Muster nach rechts verschoben werden kann um zu passen. Zeichen die eine Verschiebung des
- ** Musters sinnvoll machen, müssen daher von Rechts des Fehlschlags stammen. Die chlut[] Werte rechts des
- ** Fehlschlages sind größer oder gleich len-i+1, links davon sind alle kleiner len-i+1!
- ** Einfach und genial!
- ** HALL in "HALLL" kann nicht zum Problem werden, da HALL bereits gefunden wird, bevor der Zeiger auf das
- ** dritte "l" springt! Kein Wort wird komplett übersprungen.
- */
-
- if(len-i+1 > skip)
- j += len - i + 1; // Index an Wordende des nächsten möglichen Wortes setzen
- else
- j += skip; // Buchstaben überspringen
-
- i = len; // Vergleich wieder vom Wortende an
- }
- }
-
- if(sigs)
- {
- Printf("\n*** BREAK!\n");
- FreeVec(chlut);
- FreeVec(buf);
- return cnt;
- }
-
- if(!i)
- {
- cnt++; // Wenn i auf Null gewandert ist, hab ich ein Wort gefunden!
- j+=2*len; // j auf das Zeichen hinter den gefundenen String setzen
- }
- }
- }
- }
-
- if(IoErr())
- {
- PrintFault(IoErr(), "DOS");
- Printf("Beim Scannen der Datei ist ein Fehler aufgetreten!\n");
- return 0;
- }
-
- FreeVec(chlut);
- FreeVec(buf);
- }
- else
- {
- Printf( "Zu wenig Speicher für den Lesepuffer (%ld Bytes)!\n"
- "Bitte modifizieren Sie die Größe mittels des <InBuf>-Parameters!\n", Args.arg_InBuf);
- return 0;
- }
-
- return cnt;
- }
-